#include <windows.h>
#include <stdio.h>
#include <conio.h> 
#include <tchar.h>
#include <process.h>
#include <stdlib.h>

const char *pStrPipeNameGet = "\\\\.\\pipe\\xiaoxin_pipe_demon_eval8js_msg";
const char *pStrPipeNameSend = "\\\\.\\pipe\\xiaoxin_pipe_demon_eval8js_msg";
const int BUFFER_MAX_LEN = 1024;
char buf[BUFFER_MAX_LEN];
DWORD dwLen;
HANDLE get, mSend, mutex;
LPCRITICAL_SECTION cs;

WCHAR* toWChar(const char *c){
    WCHAR wszClassName[256];
    memset(wszClassName, 0, sizeof(wszClassName));
    MultiByteToWideChar(CP_ACP, 0, c, strlen(c) + 1, wszClassName,
    sizeof(wszClassName) / sizeof(wszClassName[0]));
    return wszClassName;
}

void beginGetThread(PVOID p){
    printf("server Get\n");
    printf("wait connect......\n");

    HANDLE hPipe = CreateNamedPipe(pStrPipeNameGet, PIPE_ACCESS_DUPLEX,
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, 0);
    if (ConnectNamedPipe(hPipe, NULL) != NULL)//等待连接。 
    {
        printf("connect success, start accept data\n");
        while (true)
        {
            WaitForSingleObject(mutex, INFINITE);
            EnterCriticalSection(cs);
            //接收客户端发送的数据 
            ReadFile(hPipe, buf, BUFFER_MAX_LEN, &dwLen, NULL);
            printf("data length %d byte\n", dwLen);
            printf("data connect:");
            for (int bufSize = 0; bufSize < (int)dwLen; bufSize++){
                putchar(buf[bufSize]);
            }
            LeaveCriticalSection(cs);
            Sleep(500);
            ReleaseSemaphore(mutex, 1, NULL);
            putchar('\n');
        }
    }
    else
    {
        printf("connect error\n");
    }
    DisconnectNamedPipe(hPipe);
    CloseHandle(hPipe);//关闭管道
}

void beginSendThread(PVOID p){
    printf("server Send\n");
    printf("wait connect......\n");

    HANDLE hPipe = CreateNamedPipe(pStrPipeNameGet, PIPE_ACCESS_DUPLEX,
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, 0);
    if (ConnectNamedPipe(hPipe, NULL) != NULL)//等待连接。 
    {
        printf("connect success, start send buffer data to B\n");
        while (true)
        {
            WaitForSingleObject(mutex, INFINITE);
            EnterCriticalSection(cs);
            WriteFile(hPipe, buf, (int)dwLen, &dwLen, NULL);
            LeaveCriticalSection(cs);
            Sleep(500);
            ReleaseSemaphore(mutex, 1, NULL);
        }
    }
    else
    {
        printf("connect error\n");
    }
    DisconnectNamedPipe(hPipe);
    CloseHandle(hPipe);//关闭管道
}

int main(int argc, _TCHAR* argv[])
{
    cs = (LPCRITICAL_SECTION)malloc(sizeof(LPCRITICAL_SECTION));
    InitializeCriticalSection(cs);
    mutex = CreateSemaphore(NULL, 1, 1, TEXT("mutex"));
    _beginthread(beginGetThread, NULL, NULL);
    _beginthread(beginSendThread, NULL, NULL);
    Sleep(INFINITE);
    DeleteCriticalSection(cs);
    return 0;
}